#include <homeworkhead.h>
#include "head.h"
int  myMkdir(task_t* pTask)//创建新目录
{
    char *cond = strtok(pTask->buf, " ");//命令，cond中内容应为mkdir
    char *dirName = strtok(NULL, " ");
   
    int ret = mkdir(dirName, 0666);
    ERROR_CHECK(ret, -1 ,"myMkdir");
    return 0;
}
int printWorkingDir(task_t *pTask){ //打印当前目录
    char buf[1024] = {0}; //buf为用来存储当前目录路径的内存空间
    getcwd(buf,1024);//获取当前目录路径
    printf("current working directory: %s\n",buf);//打印路径
    send(pTask->netFd,buf,strlen(buf),0);
}

int removeFile(task_t *pTask){//删除目标文件
    //removeFile argv[1]
    //char buf[1024];
    char delim[10] = " ";
    char *token1,*token2;
    int ret;
    token1 = strtok(pTask->buf,delim);
    token2 = strtok(NULL,delim);//分割出文件名
    struct stat fileinfo;         //定义文件属性结构体存储要删除文件属性
    ret = stat(token2,&fileinfo);//将目标文件属性存入结构体
    while(1){
        if(unlink(token2) < 0){
            printf("RMOVE ERROR!");
            break;
        }
        unlink(token2);
        if(fileinfo.st_nlink == 0){      //判断文件上是否还有链接，没有则删除成功
            printf("RMOVE COMPLETED!\n");
            break;
        }
    }
}

int cd(task_t *pTask) {
    char s[1024] = {0};
    strcpy(s, pTask->buf);
    char *w = strtok(s, " ");
    char orderName[512] = {0};
    char destPath[512] = {0};
    strcpy(orderName, w);
    if ((w = strtok(NULL, " ")) != NULL) {
        strcpy(destPath, w);
    }
    
    if (!strcmp(destPath, "-")) {
        if (strlen(pTask->prePath) == 0) {
            char s[1024] = {0};
            strcpy(s, "cd :OLDPWD未设定");
            send(pTask->netFd, s, strlen(s), 0);
            return -1;
        }
        else {
            char temp[1024] = {0};
            strcpy(temp, getcwd(NULL, 0));
            int ret = chdir(pTask->prePath);
            ERROR_CHECK(ret, -1, "chdir");
            strcpy(pTask->prePath, temp);
        }
    }
    else if (strlen(destPath) == 0 || !strcmp(destPath, "~")) {
        strcpy(pTask->prePath, getcwd(NULL, 0));
        int ret = chdir("/home");
        ERROR_CHECK(ret, -1, "chdir1");
        DIR *pHome = opendir("/home");
        struct dirent *p;
        char s[1024] = {0};     
        while ((p = readdir(pHome)) != NULL) {
            if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, "..")){
                continue;
            }
            strcat(s, p->d_name);
            break;
        }
        closedir(pHome);
        ret = chdir(s);
        ERROR_CHECK(ret, -1, "chdir2");
    }
    else {
        strcpy(pTask->prePath, getcwd(NULL, 0));
        int ret = chdir(destPath);
        if(ret == -1){
            perror("chdir");
            send(pTask->netFd,"chdir: No such file or directory!",33,0);
            return -1;
        }
        //ERROR_CHECK(ret, -1, "chdir");
        
    }
    char *str = getcwd(NULL, 0);
    //puts(str);
    send(pTask->netFd, str, strlen(str), 0);
}

int ls(task_t *pTask) {
    char s[1024] = {0};
    strcpy(s, pTask->buf);
    char *w = strtok(s, " ");
    char orderName[512] = {0};
    char destPath[512] = {0};
    strcpy(orderName, w);
    if ((w = strtok(NULL, " ")) != NULL) {
        strcpy(destPath, w);
        //puts(destPath);
    }

    DIR *pdir;
    if (strlen(destPath) == 0) {
        pdir = opendir(".");
        ERROR_CHECK(pdir, NULL, "opendir");
    }
    else if (!strcmp(destPath, "~")) {
        DIR *pdir1 = opendir("/home");
        int ret = chdir("/home");
        ERROR_CHECK(ret, -1, "chdir");

        struct dirent *p;
        char s[1024] = {0};
        DIR *pHomeDir;
        while ((p = readdir(pdir1)) != NULL) {
            strcat(s, p->d_name);
            //puts(s);
            break;
        }
        pdir = opendir(s);
        ERROR_CHECK(pdir, NULL, "opendir1");
        
    }
    else {
        pdir = opendir(destPath);
        if(pdir == NULL){
            perror("opendir");
            send(pTask->netFd,"opendir: No such file or directory!",35,0);
            return -1;
        }
    }
    struct dirent *pdirent;
    char str[1024] = {0};
    while ((pdirent = readdir(pdir)) != NULL){
        if (!strcmp(pdirent->d_name, ".") || !strcmp(pdirent->d_name, "..")){
            continue;
        }
        strcat(str, pdirent->d_name);
        strcat(str, "  ");
    }
    //puts(str);
    closedir(pdir);
    send(pTask->netFd, str, strlen(str), 0);
}

int downloadFile(task_t *pTask){
    //gets file1
    char *command = strtok(pTask->buf," ");//解析获取命令
    char *fileName = strtok(NULL," ");//解析获取文件名
    int length = strlen(fileName);
    
    train_t t;
    bzero(t.buf,sizeof(t.buf));
    t.dataLength = length;
    strcpy(t.buf,fileName);

    printf("length = %d,fileName = %s\n",length,fileName);
    
    int fd = open(fileName, O_RDWR);
    ERROR_CHECK(fd,-1,"open");
    int ret = send(pTask->netFd,&t,sizeof(t.dataLength)+ t.dataLength,MSG_NOSIGNAL);//发送文件名
    ERROR_CHECK(ret,-1,"send");
    struct stat statbuf;
    ret = fstat(fd,&statbuf);//获取文件的总大小
    ERROR_CHECK(ret,-1,"fstat");
    t.dataLength = sizeof(statbuf.st_size);//把文件的大小装入小火车
    memcpy(t.buf,&statbuf.st_size,sizeof(statbuf.st_size));
    send(pTask->netFd,&t,sizeof(t.dataLength)+t.dataLength,MSG_NOSIGNAL);
    
    char *p = (char *)mmap(NULL,statbuf.st_size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    ERROR_CHECK(p,MAP_FAILED,"mmap");
    off_t total = 0;
    while(total < statbuf.st_size){
        if(statbuf.st_size - total < sizeof(t.buf)){
            //最后一次发送
            t.dataLength = statbuf.st_size-total;
        }
        else{
            t.dataLength = sizeof(t.buf);
        }
        memcpy(t.buf,p+total,t.dataLength);//把数据装入火车车厢
        int ret = send(pTask->netFd,&t,sizeof(t.dataLength)+t.dataLength,MSG_NOSIGNAL);
        ERROR_CHECK(ret,-1,"send");
        total += t.dataLength;
    }
    munmap(p,statbuf.st_size);
    t.dataLength = 0;
    send(pTask->netFd,&t,sizeof(t.dataLength),0);
    //发送终止
    close(fd);
}
int recvn(int netFd,void *p, int n){
    int total = 0;
    int ret;
    char *pTmp = (char *)p;
    while(total < n){
        ret = recv(netFd,pTmp+total,n-total,0);
        ERROR_CHECK(ret,-1,"recv");
        total+= ret;
    }
    return 0;
}
int uploadFile(task_t *pTask){
    int dataLength;
    char name[1024] = {0};
    int ret =recvn(pTask->netFd,&dataLength,sizeof(int));//先收火车头
    ERROR_CHECK(ret,-1,"recv");
    ret = recvn(pTask->netFd,name, dataLength);//再收文件名
    ERROR_CHECK(ret,-1,"recv");
    int fd = open(name, O_RDWR|O_CREAT, 0666);
    ERROR_CHECK(fd,-1,"open");
    char buf[1024] = {0};
    long fileSize;
    recvn(pTask->netFd,&dataLength,sizeof(int));//先收火车头
    recvn(pTask->netFd,&fileSize,sizeof(fileSize));//再收文件长度
    printf("fileSize = %ld\n", fileSize);
    ftruncate(fd,fileSize);
    off_t downSize = 0;
    off_t lastSize = 0;
    off_t slice = fileSize/1000;
    struct timeval begTime,endTime;
    gettimeofday(&begTime,NULL);
    while(1){
        ret = recvn(pTask->netFd,&dataLength,sizeof(int));//先收火车头
        ERROR_CHECK(ret,-1,"recv");
        if(dataLength==0){
            break;
        }
        if(dataLength != 1000){
            printf("dataLength = %d\n", dataLength);
        }
        ret = recvn(pTask->netFd,buf,dataLength);
        ERROR_CHECK(ret,-1,"recv");
        downSize += dataLength;
        if(downSize-lastSize > slice){
            printf("%5.2lf%s\r", 100.0*downSize/fileSize,"%");
            fflush(stdout);
            lastSize = downSize;
        }
        write(fd,buf,dataLength);
    }
    printf("100.00%s\n", "%");
    gettimeofday(&endTime,NULL);
    printf("total time = %ld\n", 1000000*(endTime.tv_sec-begTime.tv_sec) + endTime.tv_usec-begTime.tv_usec);
}
